#include "XTarget.h"


XTarget::XTarget(float imass, Vector3f iposition,
								char* fname,
								bool multi)
{
	angular_velocity = 0;
	alignment = 0;
	hit = false;
	this->multipart = multi;
	this->mass = imass;

	position = iposition;
	rotationangle = 0;
	myFrame.SetOrigin(iposition.x,iposition.y,iposition.z);
	//myFrame.RotateWorld(PI/2,0.0f,1.0f,0.0f);
	//rendering
	//gltMakeSphere(myTBatch,0.1f,16,16);

	//just for testing
	impact_distance = 10;
	min_x = 0;
	max_x = 0;
	min_y = 0;
	max_y = 0;
	min_z = 0;
	max_z = 0;

	if(multipart){
		numParts = loaders::uwsmMultiCheck(fname);
		myTBatch = new GLTriangleBatch[numParts];
		loaders::uwsmMultiLoad(fname,myTBatch,min_x, max_x, min_y, max_y, min_z, max_z);
	}else{
		myTBatch = new GLTriangleBatch();
		loaders::uwsm(fname,myTBatch,min_x, max_x, min_y, max_y, min_z, max_z);
	}

	//myFrame.RotateLocalY(PI/2);
	//myFrame.RotateLocalX(-PI/2);
	myShader = gltLoadShaderPairWithAttributes(
		"phong.vert", "phong.frag", 3,
		GLT_ATTRIBUTE_VERTEX, "vVertex",
		GLT_ATTRIBUTE_NORMAL, "vNormal",
		GLT_ATTRIBUTE_TEXTURE0, "vTexture0");

	locAmbient = glGetUniformLocation(myShader, "ambientColor");
	locDiffuse = glGetUniformLocation(myShader, "diffuseColor");
	locSpecular = glGetUniformLocation(myShader, "specularColor");
	locLight = glGetUniformLocation(myShader, "vLightPosition");
	locMVP = glGetUniformLocation(myShader, "mvpMatrix");
	locMV  = glGetUniformLocation(myShader, "mvMatrix");
	locNM  = glGetUniformLocation(myShader, "normalMatrix");
	locTexture = glGetUniformLocation(myShader, "colorMap");

	width = max_x - min_x;
	height = max_y - min_y;
	depth = max_z - min_z;
}


XTarget::~XTarget(void)
{
}


void XTarget::rotate(float dt)
{
	// Rotate the target by its angular velocity (adjusted to be in Radians) around the local X-axis.

	myFrame.RotateLocal((angular_velocity * dt) * DegToRad,-1.0f,0.0f,0.0f);

	// Updates the current alignement of the targets face
	alignment += angular_velocity * dt;

	// Resets the targets alignment if it is greater than 180 degrees.  If you don't do this weirdness ensues
	if(alignment > 180)
	{
	//	alignment = alignment - 180;
	}
}


void XTarget::update(float dt)
{
	if(hit)
	{
		if(impact_distance !=0)
		{
			float tangenitalV = velocity.length() + sin(alignment);
			angular_velocity += (tangenitalV * impact_distance);  // this changed to * from / .  This gives an accurate looking solution.  Not sure about scientific accuracy though.
 			hit = false;
			this->velocity = ZERO_VEC;
		}
	}
	if(angular_velocity != 0)
	{
		//drag = 5.418 * angular_velocity * angular_velocity * dt;
		drag = angular_velocity  * dt *0.8;
		if(direction_of_spin == CLCKWISE)
		{
			angular_velocity += drag;
		}
		else
		{
			angular_velocity -= drag;
		}
	}

	rotate(dt);
}

void XTarget::getPointOfImpact(float z, float y)
{
	// calculates how far from the axis of rotation the projectile struck the target.
	z -= position.z;
	impact_distance = sqrt((z * z) + (y * y));

	// This if loop fixes the direction of rotation problem
	if(y > 0)
	{
		impact_distance *= -1;
	}
}